package texas_holdem.game;

import java.util.HashMap;
import java.util.Set;
import java.util.Vector;

import edu.android.StartGameActivity.GameState;

import texas_holdem.data.Card;
import texas_holdem.data.Deck;
import texas_holdem.data.HueristicOddsCalculator;
import texas_holdem.data.OddsCalculator;




public class Game {
	
	private HashMap<Hand, Double> _odds;
	private Hand	_hand;	
	private OddsCalculator _calculator;
	private HueristicOddsCalculator _calc;
	//private int 	_participantsNum;
	
	public Game(Hand hand, HueristicOddsCalculator calculator)
	{
		_odds = new HashMap<Hand,Double>();
		_hand = hand;
		_calculator = calculator;
		_calc = calculator;
		_hand.setOdds(_calculator.getInitOdds(_hand));
	}
	/*public Game(Hand hand, OddsCalculator calculator)
	{
		_odds = new HashMap<Hand,Double>();
		_hand = hand;
		_calculator = calculator;
		_hand.setOdds(_calculator.getInitOdds(_hand));
	}
	*/
	public Hand getHand()
	{
		return _hand;
	}
	
	public void flop(Card c1, Card c2, Card c3)
	{
		_hand.flop(c1, c2, c3);
		//calcOdds();
		//_hand.setOdds(calcOddFlop());
		_hand.setOdds(_calc.calcOdds(_hand,GameState.Flop));
	}
	public void flop(Card cards[])
	{
		_hand.flop(cards);
		_hand.setOdds(_calc.calcOdds(_hand,GameState.Flop));
		//calcOdds();
		//_hand.setOdds(calcOddFlop());
	}
	
	public void turn(Card c)
	{
		_hand.turn(c);
		_hand.setOdds(_calc.calcOdds(_hand,GameState.Turn));
		//_hand.setOdds(calcOddTurn());
	}
	public void river(Card c)
	{
		_hand.river(c); 
		_hand.setOdds(_calc.calcOdds(_hand,GameState.River));
		//_hand.setOdds(calcOddRiver());
	}
	private double calcOddFlop() {
		return calcOdd(3);
	}
	private double calcOdd(int length) {
		double count = 0;
		double oddSum = 0;
		Set<Hand> set = _odds.keySet();
		Card[] table = _hand.getTable();
		for (Hand h : set)
		{
			if (contains(length,table,h.getTable()))
			{
				count++;
				oddSum += _odds.get(h);
			}
		}
		return oddSum/count;
	}
	private boolean contains(int length, Card[] t1, Card[] t2) {
		for (int i = 0; i < length; i++)
		{
			if (!t1[i].equals(t2[i]))
				return false;
		}
		return true;
	}
	private double calcOddTurn() {
		return calcOdd(4);
	}
	private double calcOddRiver() {
		return calcOdd(5);
	}
	private void calcOdds() {
		
		Deck d = Deck.getInstance();
		Vector<Card> deck = d.getCopyOfDeck();
		Card first = _hand.getFirst();
		Card second = _hand.getSecond();
		deck.remove(first);
		deck.remove(second);
		Card [] table = _hand.getTable();
		deck.remove(table[0]);
		deck.remove(table[1]);
		deck.remove(table[2]);
		// choose 2 card for table
		
		for (int i = 0; i < deck.size(); i++)
		{
			table[3] = deck.remove(i);
			for (int j = 0; j < deck.size(); j++)
			{
				table[4] = deck.remove(j);
				// now we will choose the opponent cards
				Hand h1 = new Hand(first, second, table);
				double count = 0, win = 0;
				for (int k1 = 0; k1 < deck.size(); k1++)
				{
					Card c1 = deck.remove(k1);
					for (int k2 = k1; k2 < deck.size(); k2++)
					{
						Card c2 = deck.remove(k2);
						Hand h2 = new Hand(c1,c2,table);
						if (_calculator.strongHand(h1, h2))
							win++;
						count++;
						deck.add(k2, c2);
					}
					deck.add(k1,c1);
				}
				_odds.put(h1, new Double(win/count));
				deck.add(j,table[4]);
			}
			deck.add(i,table[3]);
		}
		table[3] = table[4] = null;
	}
	/*
	public static void main(String[] args)
	{
		OddsCalculator calculator = new OddsCalculator("docs\\initodds.txt");
		Card c1 = new Card(CardNumber.Eight,CardType.Diamond);
		Card c2 = new Card(CardNumber.Eight,CardType.Spade);
		Hand h = new Hand(c1, c2);
		Game g = new Game(h, calculator);
		System.out.println("odds before flop: " + h.getOdds());
		Card c3 = new Card(CardNumber.Eight,CardType.Heart);
		Card c4 = new Card(CardNumber.Jack,CardType.Heart);
		Card c5 = new Card(CardNumber.Ace,CardType.Heart);
		g.flop(c3, c4, c5);
		System.out.println("odds after flop: " + h.getOdds());
		Card turn = new Card(CardNumber.Eight, CardType.Club);
		g.turn(turn);
		System.out.println("odds after turn: " + h.getOdds());
		Card river = new Card(CardNumber.Two, CardType.Diamond);
		g.river(river);
		System.out.println("odds after river: " + h.getOdds());	
	}
	*/
	
	
}
